<template>
  <t-drawer
    class="t-dr"
    :keyboard="false"
    :visible="visibleDesign"
    :closable="false"
    :fullscreen="fullscreen"
    :switchFullscreen="fullscreen"
    @close="
      () => {
        $emit('cancel');
      }
    "
  >
    <a-spin :spinning="loading" :delay="100">
      <div class="flex design-header">
        <div class="logo">
          <img :src="systemLogo" alt="logo" />
          <div class="title">表单设计</div>
        </div>
        <div class="left-step" :style="leftStep">
          <!-- <a-steps v-model="currentIndex" @change="setDataSource" size="default"> -->
          <a-steps :current="currentIndex" size="default">
            <a-step
              :title="item.name"
              v-for="(item, index) in stepList"
              :key="index"
            />
          </a-steps>
        </div>
        <div class="right-btn">
          <a-button
            :class="[currentIndex == 0 ? 'buttonGray' : 'margin-right-xs']"
            icon="left"
            @click="changeCurrentIndex('left')"
            :disabled="currentIndex == 0"
            >{{ $ct("PreviousStep", "上一步") }}</a-button
          >
          <a-button
            :class="[
              currentIndex == stepList.length - 1
                ? 'buttonGray'
                : 'margin-right-xs',
            ]"
            icon="right"
            @click="changeCurrentIndex('right')"
            :disabled="currentIndex == stepList.length - 1"
            >{{ $ct("NextStep", "下一步") }}
          </a-button>
          <a-button
            :class="[
              currentIndex != stepList.length - 1
                ? 'buttonGray'
                : 'cu-btn-primary',
            ]"
            :disabled="currentIndex != stepList.length - 1"
            icon="check"
            @click="handleSubmitData"
            :loading="confirmLoading"
            >{{ $ct("save", "保存") }}</a-button
          >
          <a-button class="cancelBtn" icon="close" @click="handleClose">{{
            $ct("close", "关闭")
          }}</a-button>
        </div>
      </div>
      <basicSet
        ref="basicSet"
        :formType="formType"
        :isEdit="isEdit"
        :interfaceUuid.sync="interfaceUuid"
        v-show="currentIndex === 0"
      ></basicSet>

      <template v-if="formType !== 'viewData'">
        <dataSet
          ref="dataSet"
          :isEdit="isEdit"
          v-show="currentIndex === 1"
          @change="dataConfigChange"
        ></dataSet>
        <form-view
          style="height: calc(100vh - 56px);"
          ref="formView"
          v-show="currentIndex === 2"
          :basicData="basicSetting"
          :basicsUuid="basicsUuid"
          :tName="tName"
          :isEdit="isEdit"
          @close="
            () => {
              $emit('cancel');
            }
          "
          @save="
            () => {
              $emit('ok');
            }
          "
        ></form-view>
      </template>

      <span
        v-show="
          currentIndex === 3 || (formType === 'viewData' && currentIndex === 1)
        "
      >
        <web-list-page
          v-show="platformKey === 'desktop'"
          ref="webListPage"
          :platformKey="platformKey"
          :activeKey="activeKey"
          :dataSource="dataSource"
          :dataField="webDataField"
          :dataSearch="webDataSearch"
          :formType="formType"
          @activeKeyChange="(e) => (activeKey = e)"
          @dataChange="configDataChange"
          @changePlatform="changePlatform"
        ></web-list-page>

        <app-list-page
          v-show="platformKey === 'mobile'"
          ref="appListPage"
          :platformKey="platformKey"
          :activeKey="activeKey"
          :dataSource="dataSource"
          :dataField="appDataField"
          :dataSearch="appDataSearch"
          :formType="formType"
          @activeKeyChange="(e) => (activeKey = e)"
          @dataChange="configDataChange"
          @changePlatform="changePlatform"
        ></app-list-page>
      </span>

      <vue-bpmn
        ref="bpmnData"
        style="overflow: hidden;height: calc(100vh - 56px);background-color: #fff;"
        v-show="currentIndex === 4"
        product="flowable"
        @close="
          () => {
            $emit('cancel');
          }
        "
      ></vue-bpmn>
    </a-spin>
  </t-drawer>
</template>

<script>
import cloneDeep from "lodash.clonedeep";
import { mapGetters } from "vuex";
import basicSet from "./basicSet";
import dataSet from "./dataSet";
import webListPage from "./webListPage";
import appListPage from "./appListPage";
import formView from "@/components/TopVUI/k-form-design/packages/KFormDesign/form.vue";
import VueBpmn from "@/components/TopVUI/bpmn/VueBpmn";
import { axios } from "@/utils/request";
export default {
  provide() {
    return {
      formList: () => this.formList,
    };
  },
  components: {
    basicSet,
    dataSet,
    webListPage,
    appListPage,
    formView,
    VueBpmn,
  },
  props: {
    visibleDesign: {
      type: Boolean,
    },
    model: {
      type: Object,
      default: () => null,
    },
    basicsUuid: {
      type: String,
      default: () => "",
    },
    formType: {
      type: String,
      default: () => "",
    },
    isEdit: {
      type: Boolean,
      default: () => false,
    },
  },
  data() {
    return {
      fullscreen: true,
      currentIndex: 0,
      stepList: [
        {
          name: this.$ct("systemConfigIndex", "基础配置"),
          key: 1,
        },
        {
          name: this.$ct("DataConfiguration", "数据配置"),
          key: 2,
        },
        {
          name: this.$ct("FormDesign", "表单设计"),
          key: 3,
        },
        {
          name: this.$ct("ListDesign", "列表设计"),
          key: 4,
        },
      ],
      basicSetting: {
        basicLayout: "default",
      },
      dataSource: [],
      webDataField: [],
      appDataField: [],
      webDataSearch: [],
      appDataSearch: [],
      activeKey: "1", //列表属性
      loading: false,
      confirmLoading: false,
      delayTime: 500,
      tName: "",
      record: {},
      leftStep: {
        width: "calc(70% - 160px)",
        padding: "0 10%",
      },
      formList: {},
      initialLoad: true,
      platformKey: "desktop",
      interfaceUuid: "",
    };
  },
  computed: {
    ...mapGetters(["configData"]),
    systemLogo() {
      let index = this.configData.findIndex(
        (item) => item.code === "systemLogo"
      );
      if (index >= 0) {
        return this.configData[index].value;
      } else {
        return "https://zysd-shanghai.oss-cn-shanghai.aliyuncs.com/emis/logo.png";
      }
    },
  },
  methods: {
    getData(record) {
      this.loading = true;
      this.record = record;
      this.$post("/form/formBasicConfigure/getDetailByUuid", {
        uuid: record.uuid,
      }).then((res) => {
        this.$refs.basicSet.model = res.formBasicConfigure;
        if (this.formType !== "viewData") {
          this.$refs.dataSet.loadData(res.formDatabase);
          this.$refs.formView.loadData(res.formDesign);
        }
        this.formList = res.formList;
        this.loading = false;
      });
    },
    handleSubmitData() {
      const that = this;
      // that.$refs.listPage.getListData();
      let webData = {
        ...that.$refs.webListPage.getListData(),
      };
      let appData = {
        ...that.$refs.appListPage.getListData(),
      };
      if (webData.listData.length < 1 && that.formType != "createPage") {
        return that.$message.error("请选择web端列表字段", 1.5);
      }
      if (appData.listData.length < 1 && that.formType != "createPage") {
        return that.$message.error("请选择app端列表字段", 1.5);
      }
      let basicConfigure = that.$refs.basicSet.getBasicData();
      basicConfigure.type = that.formType;

      let database;
      let formData;
      if (this.formType !== "viewData") {
        database = that.$refs.dataSet.getDataBase();
        formData = that.$refs.formView.getListData();
      }
      let webListData = cloneDeep(that.$refs.webListPage.getListData());
      let appListData = that.$refs.appListPage.getListData();
      //顶部配置按钮
      webListData.listProData.topButtonList = webListData.listProData.topButtonList.filter(
        (v) => v.checked
      );
      //行内配置按钮
      webListData.listProData.lineButtonList = webListData.listProData.lineButtonList.filter(
        (v) => v.checked
      );
      let param = {
        basicConfigureJson: JSON.stringify(basicConfigure),
        databaseJson: JSON.stringify(database),
        fromJson: formData ? JSON.stringify(formData.webJson) : undefined,
        appDesignJson: formData ? JSON.stringify(formData.appJson) : undefined,
        webListJson: JSON.stringify(webListData),
        appListJson: JSON.stringify(appListData),
      };
      console.log({
        basicConfigureJson: basicConfigure,
        databaseJson: database,
        fromJson: formData ? formData.webJson : undefined,
        appDesignJson: formData ? formData.appJson : undefined,
        webListJson: webListData,
        appListJson: appListData,
      });
      if (that.isEdit) {
        const modal = that.$confirm({
          title: "提示",
          content: "确定要保存吗",
          okText: "保存",
          cancelText: "取消",
          closable: true,
          onOk() {
            param.newVersion = false;
            that.handleSubmitSave(param);
          },
          onCancel(e) {
            // if(e.triggerCancel != true){
            // 	param.newVersion = true
            // 	that.handleSubmitSave(param)
            // }
            modal.destroy();
          },
        });
      } else {
        that.handleSubmitSave(param);
      }

      // if (appDetailUuid) {
      // 	url = "/form/formBasicConfigure/update";
      // 	param.uuid = appDetailUuid;
      // } else {
      // url = "/form/formBasicConfigure/save";
      // }
    },
    handleSubmitSave(param) {
      this.loading = true;
      this.confirmLoading = true;
      axios
        .post("/form/formBasicConfigure/save", param, {
          headers: {
            "Content-Type": "application/json;charset=UTF-8",
          },
        })
        .then((res) => {
          console.log(res);
          if (res.statusCode !== 300) {
            this.$message.success(
              res.message ? res.message : "操作成功！",
              1.5
            );
            this.$emit("ok");
          } else {
            this.$message.error(res.message ? res.message : "操作失败", 1.5);
          }
          this.loading = false;
          this.confirmLoading = false;
        });
    },
    dataConfigChange() {
      this.$refs.formView.clearTableName();
    },
    // 步骤切换验证
    changeCurrentIndex(type) {
      if (type == "right" && this.currentIndex == 0) {
        let key = this.$refs.basicSet.validateData();
        if (key == null) return this.$message.error("请将信息填写完整", 1.5);

        if (this.formType !== "viewData") {
          this.$refs.dataSet.tableName = this.$refs.basicSet.getBasicData().name;
          if (!this.isEdit) {
            this.$refs.dataSet.generateTableName();
          }
        } else {
          this.dataSource = [];
          this.$post("/system/sysInterfaceManagement/querySqlColumn", {
            uuid: this.interfaceUuid,
          }).then((res) => {
            if (res.statusCode === 200) {
              res.data.forEach((item) => {
                this.dataSource.push({
                  filed: item,
                  filedName: item,
                  align: "left",
                  fixed: "",
                  width: null,
                  type: "contain",
                });
              });
            } else {
              this.$message.error(
                res.message
                  ? res.message
                  : "数据请求失败，请查看接口格式是否正确"
              );
            }

            // this.$refs.webListPage.viewSelect();
            // this.$refs.appListPage.viewSelect();

            let webList = JSON.parse(this.formList.webListJson);
            let appList = JSON.parse(this.formList.appListJson);

            this.webDataField = webList.listData;
            this.appDataField = appList.listData;
            this.webDataSearch = webList.searchData.list;
            this.appDataSearch = appList.searchData.list;

            this.$refs.webListPage.selectedRows = webList.listData;
            this.$refs.appListPage.selectedRows = appList.listData;
            this.$refs.webListPage.selectedRowKeys = webList.listData.map(
              (e) => e.filed
            );
            this.$refs.appListPage.selectedRowKeys = appList.listData.map(
              (e) => e.filed
            );

            this.$refs.webListPage.selectedRowsSearch = webList.searchData.list;
            this.$refs.appListPage.selectedRowsSearch = appList.searchData.list;
            this.$refs.webListPage.selectedRowKeysSearch = webList.searchData.list.map(
              (e) => e.filed
            );
            this.$refs.appListPage.selectedRowKeysSearch = appList.searchData.list.map(
              (e) => e.filed
            );
          });
        }
      }
      if (this.formType !== "viewData") {
        let cardKey = this.$refs.dataSet.cardKey; // 选择的表类型（自动生成还是选择表）
        this.$refs.formView.tableDataType = cardKey;
        if (type == "right" && this.currentIndex == 1) {
          let dataConfigDataSource = this.$refs.dataSet.dataSource;
          const randomTableName = this.$refs.dataSet.randomTableName;
          if (cardKey == 1) {
            if (!randomTableName) {
              return this.$message.error("表名不能为空！", 1.5);
            }
            const regex = /^[a-zA-Z0-9_]+$/;
            if (!regex.test(randomTableName)) {
              return this.$message.error(
                "表名只能包含字母、数字、下划线！",
                1.5
              );
            }
          }
          // 从数据配置获取表数据
          let obj = {
            type: cardKey,
            data: dataConfigDataSource.map((item) => {
              return {
                tableName: item.tableName,
                tableRemarks: item.tableRemarks,
              };
            }),
            fields: this.$refs.dataSet.columnData,
          };
          this.$refs.formView.fromDataConfig = obj;

          if (cardKey == 2 && !dataConfigDataSource.length) {
            return this.$message.error("请选择数据表", 1.5);
          }
          for (let i = 0; i < dataConfigDataSource.length; i++) {
            if (!dataConfigDataSource[i].associatedFields) {
              return this.$message.error("请选择关联字段！", 1.5);
            }
          }
          let firstTableCat = dataConfigDataSource[0]?.tableCat; // 保存第一个对象的 tableCat 值
          for (let i = 1; i < dataConfigDataSource.length; i++) {
            if (dataConfigDataSource[i].tableCat !== firstTableCat) {
              return this.$message.error(
                "请不要在一张表单内引入两个数据库内的数据表!",
                1.5
              );
            }
          }
        }
        if (type == "right" && this.currentIndex == 2 && cardKey == 2) {
          // 验证表名
          let table = this.$refs.formView.validateTableName();
          if (cardKey == 2 && table) {
            return this.$message.error(`${table.label}表名不能为空`, 1.5);
          }
          // 验证子表
          let subTable = this.$refs.formView.validateSubTable();
          if (subTable && subTable === "isNull") {
            return this.$message.error("请先设计子表！", 1.5);
          } else if (cardKey == 2 && subTable) {
            return this.$message.error(
              `${subTable.label}数据字段不能为空`,
              1.5
            );
          }
          // 验证数据字段
          let field = this.$refs.formView.validateFieldName(cardKey);
          if (field && field == "isNull") {
            return this.$message.error(
              "表单内必须要有最少一个字段绑定数据库字段！",
              1.5
            );
          } else if (field && !~["text", "batch"].indexOf(field.type)) {
            return this.$message.error(`${field.label}数据字段不能为空`, 1.5);
          }
        }
        if (type == "right" && this.currentIndex == 2 && cardKey == 1) {
          let ifUrl = this.$refs.formView.validateIfUrl();
          if (ifUrl) {
            return this.$message.error(
              `请确认【${ifUrl.label}】是否选择远端数据、储存字段、显示字段`,
              1.5
            );
          }
        }
      }
      if (type == "left") {
        this.currentIndex -= 1;
      } else {
        this.currentIndex += 1;
      }

      // if(this.isEdit && this.initialLoad){
      // 	if(this.currentIndex == 3){
      // 		this.initialLoad = false
      // 	}
      // 	let data = JSON.parse(this.formList.listJson)
      // 	this.dataSource = data.listData
      // 	this.dataField = data.listProData
      // 	this.$refs.listPage.listProData = data.listProData
      // 	this.dataSearch = data.searchData.list
      // 	this.$refs.listPage.mergeQuery = data.searchData.mergeQuery
      // }else{
      // 	this.setDataSource(this.currentIndex);
      // }
      this.setDataSource(this.currentIndex);
      if (this.currentIndex == 3 && !this.isEdit) {
        this.$refs.webListPage.allSelect();
        this.$refs.appListPage.allSelect();
      }
    },
    setDataSource(e) {
      // let basic = this.$refs.basicSet.getBasicData();
      // this.basicSetting = basic;
      if (e === 3) {
        this.dataSource = [];
        // this.dataField = []
        // this.dataSearch= []
        let data = this.$refs.formView.getListData().webJson;
        this.getSourceDataByLayout(data); //根据布局获取source

        if (this.formList?.webListJson) {
          let webList = JSON.parse(this.formList.webListJson);
          let appList = JSON.parse(this.formList.appListJson);
          // this.dataSource = formList.listData

          // formList.listData.forEach(item => {
          // 	this.dataSource.forEach((e, index) => {
          // 		if(item.filed === e.filed){
          // 			this.dataSource[index] = item
          // 		}
          // 	})
          // })

          // 列表设计数据回显
          this.webDataField = webList.listData;
          this.appDataField = appList.listData;
          this.$refs.webListPage.listProData = webList.listProData;
          this.$refs.appListPage.listProData = appList.listProData;
          this.webDataSearch = webList.searchData.list;
          this.appDataSearch = appList.searchData.list;
          this.$refs.webListPage.queryType = webList.searchData.queryType;
          this.$refs.appListPage.queryType = appList.searchData.queryType;
          this.$refs.webListPage.upperLimit = webList.searchData.upperLimit;
          this.$refs.appListPage.upperLimit = appList.searchData.upperLimit;

          this.$refs.webListPage.selectedRows = webList.listData;
          this.$refs.appListPage.selectedRows = appList.listData;
          this.$refs.webListPage.selectedRowKeys = webList.listData.map(
            (e) => e.filed
          );
          this.$refs.appListPage.selectedRowKeys = appList.listData.map(
            (e) => e.filed
          );

          this.$refs.webListPage.selectedRowsSearch = webList.searchData.list;
          this.$refs.appListPage.selectedRowsSearch = appList.searchData.list;
          this.$refs.webListPage.selectedRowKeysSearch = webList.searchData.list.map(
            (e) => e.filed
          );
          this.$refs.appListPage.selectedRowKeysSearch = appList.searchData.list.map(
            (e) => e.filed
          );
        }

        let hashField = {};
        this.webDataField = this.webDataField.reduce(function(item, next) {
          hashField[next.filed]
            ? ""
            : (hashField[next.filed] = true && item.push(next));
          return item;
        }, []);
        this.appDataField = this.appDataField.reduce(function(item, next) {
          hashField[next.filed]
            ? ""
            : (hashField[next.filed] = true && item.push(next));
          return item;
        }, []);
        let hashSearch = {};
        this.webDataSearch = this.webDataSearch.reduce(function(item, next) {
          hashSearch[next.filed]
            ? ""
            : (hashSearch[next.filed] = true && item.push(next));
          return item;
        }, []);
        this.appDataSearch = this.appDataSearch.reduce(function(item, next) {
          hashSearch[next.filed]
            ? ""
            : (hashSearch[next.filed] = true && item.push(next));
          return item;
        }, []);
      }
    },
    //根据布局获取source
    getSourceDataByLayout(data) {
      let dataList = data?.list || data;
      dataList.forEach((val) => {
        if (
          !~[
            "table",
            "grid",
            "tabs",
            "card",
            "batch",
            "divider",
            "text",
            "button",
            "alert",
            "html",
            "qrCode",
            "barCode",
            "videoPlayer",
            "hyperlink",
            "hyperlinkPro",
            "groupTitle",
            "blank",
          ].indexOf(val.type)
        ) {
          this.getSourceDataList(val); //数据push
        } else if (~["grid", "tabs"].indexOf(val.type)) {
          //栅格、选项卡布局
          val.columns.forEach((el) => {
            this.getSourceDataByLayout(el.list);
          });
        } else if (~["card"].indexOf(val.type)) {
          //卡片布局
          this.getSourceDataByLayout(val.list);
        } else if (val.type == "table") {
          //表格布局
          val.trs.forEach((tr) => {
            tr.tds.forEach((td) => {
              this.getSourceDataByLayout(td.list);
            });
          });
        }
      });
    },
    //获取数据
    getSourceDataList(val) {
      let obj = {
        filed: val.model,
        filedName: val.label,
        filedType: val.type,
        align: "left",
        fixed: "",
        width: null,
        type: "contain", // 列表设计查询方式
      };
      if (val.options.showTime) {
        obj.showTime = true;
      }
      // 禁止出现在列表配置的控件
      if (
        !~[
          "uploadFile",
          "uploadFile2",
          "uploadImg",
          "slider",
          "editor",
          "button",
          "text",
          "rate",
          "highUploadImg",
          "calcFormula",
          "icon",
          "color",
        ].indexOf(val.type)
      ) {
        this.dataSource.push(obj);
      }
    },
    configDataChange(data, text, type) {
      if (text === "list") {
        if (this.formType !== "viewData" && type === "desktop") {
          this.webDataField = data;
        } else if (type === "desktop") {
          this.webDataField = data;
          this.appDataField = data;
        } else {
          this.appDataField = data;
        }
      }
      // if (text === "list") {
      // 	if(type === "desktop"){
      // 		this.webDataField = data;
      // 	}else{
      // 		this.appDataField = data;
      // 	}
      // }
      if (text === "search") {
        if (this.formType !== "viewData" && type === "desktop") {
          this.webDataSearch = data;
        } else if (type === "desktop") {
          this.webDataSearch = data;
          this.appDataSearch = data;
        } else {
          this.appDataSearch = data;
        }
        // if(type === "desktop"){
        // 	this.webDataSearch = data;
        // }else{
        // 	this.appDataSearch = data;
        // }
      }
    },
    changeBasicSet(e, key) {
      // this.basicSet[key] = e
    },
    handleClose() {
      let that = this;
      that.$confirm({
        title: "警告",
        content: "关闭后所有未保存的数据将会清空，请谨慎操作！",
        okText: "关闭",
        okType: "danger",
        cancelText: "取消",
        onOk() {
          that.$emit("cancel");
          that.activeKey = "1";

          if (that.formType !== "viewData") {
            that.$refs.formView.data.list = [];
            that.$refs.formView.selectItem = { key: "" };
            that.$refs.formView.options = {};
          }

          that.$refs.webListPage.data = [];
          that.$refs.appListPage.data = [];
          that.$refs.webListPage.selectedRowKeys = [];
          that.$refs.appListPage.selectedRowKeys = [];
        },
      });
    },
    changePlatform(e) {
      this.platformKey = e;
    },
  },
};
</script>

<style lang="less" scoped>
@basehight: 56px;

.buttonGray,
.buttonGray:hover {
  color: #d9d9d9;
  margin-right: 10px;
  background: #fafafa;
}

.t-dr {
  .design-header {
    width: 100%;
    height: @basehight;
    line-height: @basehight;
    border-bottom: 1px solid #e8e8e8;
    background-color: #fff;

    .left-step {
      // width: 70%;
      // padding: 0 20%;

      .ant-steps {
        padding-top: 10px;
      }
    }
  }
}

/deep/ .ant-drawer-header,
/deep/ .ant-drawer-body {
  padding: 0 !important;
}

.right-btn {
  width: 30%;
  display: flex;
  align-items: center;
  justify-content: flex-end;
  padding-right: 20px;
}

/deep/.bpmn-viewer-container {
  height: calc(100vh - 88px);
}

.cancelBtn {
  background: #e4746f !important;
  border-color: #e4746f !important;
  color: #fff;
}

.cancelBtn:hover {
  opacity: 0.9;
}

/deep/.ant-drawer-content {
  background-color: #f0f2f5;
}

.logo {
  width: 160px;
  padding-left: 45px;
  display: flex;
  align-items: center;
  img {
    width: 32px;
    height: 32px;
  }
  .title {
    font-weight: 500;
    display: inline;
    font-size: 16px;
    padding-left: 10px;
  }
}
</style>
